import React, { forwardRef, useImperativeHandle, useState } from 'react'
import Player from 'xgplayer'

import video from '../../store/video'
import recordTime from '../../store/record-time'
import { getPath, setVideoDom, focusScreen, getBoundingClientRect } from '../../util/index'

import './styles/video-player.scss'
import common from '../../store/common'

const VideoPlayer = forwardRef(({ val }, ref) => {
  const { event$ } = common

  const [playProgress, setPlayProgress] = useState({ duration: 0, currentTime: 0 })

  useImperativeHandle(ref, () => ({
    playVideo,
    pauseVideo,
    stopVideo,
    playProgress,
  }))

  function initPlayer(url, id, isLive = false) {
    const player = new Player({
      el: document.getElementById(`${id}`).firstChild.lastChild,
      controls: false,
      autoplay: true,
      // fitVideoSize: 'auto',
      fluid: true,
      url,
      closePlayerBlur: true,
      closeFocusVideoFocus: true,
      enableContextmenu: false,
      closeVideoClick: true,
      closeVideoPreventDefault: true,
      closeVideoStopPropagation: true,
      ignores: ['replay'],
      volume: 0,
    })
    setTimeout(() => {
      addEventListener(player.video)
      player.video.play()
    }, 50)
    console.log(player)
    player.video.crossOrigin = 'anonymous'
    return player
  }

  function playVideo(id, url) {
    const _id = id ? id : video.curScreenId
    const screen = video.findScreenById(_id)
    if (screen) {
      const { player } = screen
      if (player) {
        // 继续播放
        player.play()
      } else {
        const player = initPlayer(url, id)
        video.addPlayer(_id, player)
      }
      afterPlayOrPause('pause')
    }
  }

  function pauseVideo(id) {
    const _id = id ? id : video.curScreenId
    const screen = video.findScreenById(_id)
    if (screen) {
      screen.player.video.pause()
      afterPlayOrPause('play')
    }
  }

  function afterPlayOrPause(status) {
    event$.emit({ action: 'videoStatus', val: status })
  }

  function stopVideo(screenId) {
    const id = screenId ? screenId : video.curScreenId
    if (setVideoDom(id, 'remove')) {
      video.removePlayer(id)
      afterStopVideo(id)
    }
  }

  function afterStopVideo(screenId) {
    const id = screenId ? screenId : video.curScreenId
    event$.emit({ action: 'stopVideo', val: id })
    event$.emit({ action: 'videoStatus', val: 'stop' })
    video.setStatus(screenId, 'stop')
    event$.emit({ action: 'resetTime' })
    recordTime.removeTimeArray(id)
  }

  function setVideoStatus({ path }, status) {
    video.setScreenByParams(getPath(path)?.id, ['status'], [status])
  }

  function addEventListener(dom) {
    const listeners = [
      {
        event: 'play',
        func: (e) => {
          setVideoStatus(e, 'pause')
        },
      },
      {
        event: 'canplay',
        func: (e) => {},
      },
      {
        event: 'pause',
        func: (e) => {
          setVideoStatus(e, 'play')
        },
      },
      {
        event: 'ended',
        func: (e) => {
          setVideoStatus(e, 'stop')
          afterStopVideo()
        },
      },
      {
        event: 'progress', // 正在请求数据
        func: (e) => {
          console.log('progress')
        },
      },
      {
        event: 'error', // 请求数据遇到错误
        func: (e) => {
          console.log('error')
        },
      },
      {
        event: 'waiting', // 等待数据，并非错误
        func: (e) => {
          console.log('waiting')
        },
      },
      {
        event: 'timeupdate',
        func: (e) => {
          const { path, target } = e
          const id = getPath(path)?.id
          if (id && id === video.curScreenId) {
            const { duration, currentTime } = target
            setPlayProgress({ duration, currentTime })
            recordTime.addTimeArray(id, { duration, currentTime })
          }
        },
      },
      {
        event: 'click',
        func: (e) => {
          focusScreen(getPath(e.path).id)
        },
      },
      {
        event: 'contextmenu',
        func: (e) => {
          e.preventDefault()
          const { clientX: x, clientY: y, path } = e
          event$.emit({ action: 'showRightMenu', val: { pos: { x, y }, screenId: getPath(path)?.id } })
        },
      },
      {
        event: 'ratechange',
        func: (e) => {},
      },
      {
        event: 'volumechange',
        func: (e) => {},
      },
    ]
    for (const { event, func } of listeners) {
      dom.addEventListener(event, (e) => {
        func(e)
      })
    }
  }

  return <></>
})

export default VideoPlayer
